package legumes.client.ui.widgets.form;

import java.util.Date;

import legumes.client.resources.PNResources;
import legumes.client.services.callbacks.LogCallback;
import legumes.client.services.callbacks.ResetPasswordCallback;
import legumes.client.services.callbacks.WhoAmICallback;
import legumes.client.services.util.rpc.RPCCallSequencer;
import legumes.client.ui.Authentication;
import legumes.client.ui.widgets.window.connexion.CreateNewAccountWindow;
import legumes.shared.domain.CustomerDTO;

import com.google.gwt.user.client.Cookies;
import com.smartgwt.client.types.Alignment;
import com.smartgwt.client.types.KeyNames;
import com.smartgwt.client.util.SC;
import com.smartgwt.client.widgets.Label;
import com.smartgwt.client.widgets.Window;
import com.smartgwt.client.widgets.events.CloseClickHandler;
import com.smartgwt.client.widgets.events.CloseClientEvent;
import com.smartgwt.client.widgets.form.DynamicForm;
import com.smartgwt.client.widgets.form.fields.ButtonItem;
import com.smartgwt.client.widgets.form.fields.CheckboxItem;
import com.smartgwt.client.widgets.form.fields.HeaderItem;
import com.smartgwt.client.widgets.form.fields.LinkItem;
import com.smartgwt.client.widgets.form.fields.PasswordItem;
import com.smartgwt.client.widgets.form.fields.TextItem;
import com.smartgwt.client.widgets.form.fields.events.ClickEvent;
import com.smartgwt.client.widgets.form.fields.events.ClickHandler;
import com.smartgwt.client.widgets.form.fields.events.KeyPressEvent;
import com.smartgwt.client.widgets.form.fields.events.KeyPressHandler;
import com.smartgwt.client.widgets.layout.VLayout;

public class ConnexionForm extends DynamicForm {

	private TextItem loginTextItem;
	private PasswordItem passWordItem;
	private CheckboxItem stayConnectedCheckBox;
	private boolean withAddNewUserLink;
	private ButtonItem validateItem;
	
	public ConnexionForm(boolean withAddNewUserLink_) {
		super();
		withAddNewUserLink = withAddNewUserLink_;
		buildGui();
		setStyleName("ConnexionFormCls");
	}

	public ConnexionForm(){
		this(true);
	}
	
	private void buildGui(){
		setAlign(Alignment.CENTER);
		
		HeaderItem header = new HeaderItem();  
        header.setDefaultValue("Connectez vous avec votre email :");  
        
        KeyPressHandler enterKeyPressHandler = new KeyPressHandler() {
			
			@Override
			public void onKeyPress(KeyPressEvent event) {
				if( event.getKeyName().equalsIgnoreCase(KeyNames.ENTER)){
					onValidateButtonClicked();
				}
			}
		};
	
		loginTextItem = new TextItem();
		loginTextItem.setTitle("Nom d'utilisateur");  
		loginTextItem.setValue("root@root.fr");
		loginTextItem.addKeyPressHandler(enterKeyPressHandler);
		
		passWordItem = new PasswordItem();
		passWordItem.setTitle("Mot de passe");
		passWordItem.addKeyPressHandler(enterKeyPressHandler);
		//TODO SMA Remove password
		// The real password is the same without the last letter "wkjfff"
		passWordItem.setValue("wkjffff");
		
		stayConnectedCheckBox = new CheckboxItem("stayConnected", "Rester connecté");
		stayConnectedCheckBox.setTabIndex(999);
		stayConnectedCheckBox.addKeyPressHandler(enterKeyPressHandler);
		
		
		validateItem = new ButtonItem();
        validateItem.setTitle("Connexion");
        validateItem.setStartRow(false);
        validateItem.setEndRow(false);
        validateItem.setAlign(Alignment.CENTER);
        validateItem.setIcon(PNResources.INSTANCE.validateIcon().getURL());
        validateItem.addClickHandler(new ClickHandler() {  
            public void onClick(ClickEvent event) {  
            	onValidateButtonClicked();
            }  
        });  
        
        if(withAddNewUserLink){
        	LinkItem newAccountItem = new LinkItem();
	        newAccountItem.setShowTitle(false);
	        newAccountItem.setTextBoxStyle("newAccountItemCls");
	        newAccountItem.setLinkTitle("<img src=\"" + PNResources.INSTANCE.userAddIcon().getURL() + "\" />&nbsp;<i>Créer un compte : rapide et gratuit !</i>");
	        newAccountItem.setAlign(Alignment.CENTER);
	        newAccountItem.setTabIndex(101);
	        newAccountItem.setColSpan(4);
	//        newAccountItem.setIcon(PNResources.INSTANCE.userAddIcon().getURL());
	        newAccountItem.addClickHandler(new ClickHandler() {
				
				@Override
				public void onClick(ClickEvent event) {
					showNewAccountDialog();
				}
			});
	        
	        LinkItem forgetPasswordItem = new LinkItem();
	        forgetPasswordItem.setShowTitle(false);
	        forgetPasswordItem.setLinkTitle("<img src=\"" + PNResources.INSTANCE.lockOpenIcon().getURL() + "\" />&nbsp;<i>Mot de passe oubli&eacute; ?</i>");
	        forgetPasswordItem.setAlign(Alignment.CENTER);
	        forgetPasswordItem.setTabIndex(102);
	//        newAccountItem.setIcon(PNResources.INSTANCE.userAddIcon().getURL());
	        forgetPasswordItem.addClickHandler(new ClickHandler() {
				
				@Override
				public void onClick(ClickEvent event) {
					showForgetPasswordDialog();
				}
			});
	        
	        setFields(header, loginTextItem, passWordItem, 
	        		stayConnectedCheckBox, 
	        		forgetPasswordItem, validateItem, newAccountItem);
        } else {
        	setFields(header, loginTextItem, passWordItem, 
	        		stayConnectedCheckBox, 
	        		validateItem);
        }
	}
	
	private void onValidateButtonClicked(){
		ConnexionForm.this.validate(false);
	    doLoggin(loginTextItem.getValueAsString(),
	    		passWordItem.getValueAsString() );
	
	}
	private void doLoggin(final String login_, final String password_){
		RPCCallSequencer onLogCallSequencer = new RPCCallSequencer();
		final LogCallback logCallback = new LogCallback(
				login_, password_);
		onLogCallSequencer.addCall(logCallback);
		onLogCallSequencer.addRunnable(new Runnable() {
			public void run() {
				if (logCallback.hasSucceed()) {
					RPCCallSequencer callSequencer = new RPCCallSequencer();
					final WhoAmICallback whoAmIallback = new WhoAmICallback();
					callSequencer.addCall(whoAmIallback);
					callSequencer.addRunnable(new Runnable() {
						public void run() {
							CustomerDTO customerDTO = whoAmIallback.getCustomerDTO();
								
							Authentication.setCustomer(customerDTO);
							onUserConnected(customerDTO);
							if(stayConnectedCheckBox.getValueAsBoolean()){
								String sessionID = logCallback.getSessionID();
								final long DURATION = 1000 * 60 * 60 * 24 * 14; //duration remembering login. 2 weeks in this example.
							    Date expires = new Date(System.currentTimeMillis() + DURATION);
							    Cookies.setCookie("sid", sessionID, expires, null, "/", false);
							}
						}
					});
					callSequencer.callSequence();
				} else {
					Authentication.setCustomer(null);
					com.google.gwt.user.client.Window.alert(logCallback.getThrowable()
							.getMessage());
				}
			}
		});
		onLogCallSequencer.callSequence();
	}
	

	public void showNewAccountDialog() {
		new CreateNewAccountWindow(){

			@Override
			protected void onCustomerAccountCreated(String email_,
					String password_) {
				doLoggin(email_, password_);
			}
		};
	}
	
	private void showForgetPasswordDialog(){
		final Window dialogWindow = new Window();
		dialogWindow.setTitle("<img src=\"" + PNResources.INSTANCE.lockOpenIcon().getURL() + "\" />&nbsp;Mot de passe oubli&eacute; ?");
		dialogWindow.setWidth(450);
		dialogWindow.setHeight(220);
		dialogWindow.setMargin(10);
		dialogWindow.setShowCloseButton(true);
		dialogWindow.setShowMinimizeButton(false);
		dialogWindow.setAutoCenter(true);
		dialogWindow.setShowModalMask(true);
		dialogWindow.addCloseClickHandler(new CloseClickHandler() {  
            public void onCloseClick(CloseClientEvent event) {  
            	dialogWindow.destroy();  
            }  
        });
		
		final DynamicForm formPanel = new DynamicForm(); 
		formPanel.setWidth100();
		formPanel.setHeight100();
		formPanel.setMargin(5);
		formPanel.setNumCols(4);
		formPanel.setTitleWidth(200);
		
		final TextItem email = new TextItem("email", "E-mail");
		email.setColSpan(4);
		
		ButtonItem ok = new ButtonItem("ok", "Valider");
		ok.setStartRow(false);
		ok.setEndRow(false);
		ok.setColSpan(2);
		ok.setAlign(Alignment.CENTER);
		ok.setIcon(PNResources.INSTANCE.validateIcon().getURL());
		ok.addClickHandler(new ClickHandler() {
			
			@Override
			public void onClick(ClickEvent event) {
				formPanel.validate();
				
				RPCCallSequencer callSequencer = new RPCCallSequencer();
				
				final ResetPasswordCallback addCustomerCallback = new ResetPasswordCallback(email.getValueAsString());
				callSequencer.addCall(addCustomerCallback);
				callSequencer.addRunnable(new Runnable() {
					public void run() {
						String errMsg = addCustomerCallback.getErrorMessage();
						if(errMsg == null){
							SC.say("Mot de passe réinitialisé", "Un mail vient de vous être envoyé avec votre nouveau mot de passe.");
						} else {
							SC.warn("Erreur lors de la réinitialisation de votre mot de passe pour l'email : " + addCustomerCallback.getEmail() + " : " + errMsg);
						}
						
					}
				});
				callSequencer.callSequence();
			}
		});
		
		ButtonItem cancel = new ButtonItem("cancel", "Annuler");
		cancel.setStartRow(true);
		cancel.setEndRow(false);
		cancel.setAlign(Alignment.CENTER);
		cancel.setColSpan(2);
		cancel.setTabIndex(100);
		cancel.setIcon(PNResources.INSTANCE.cancelIcon().getURL());
		cancel.addClickHandler(new ClickHandler() {
			
			@Override
			public void onClick(ClickEvent event) {
				dialogWindow.hide();
			}
		});
		
		
		formPanel.setItems(email, cancel, ok);
		VLayout vl = new VLayout();
		Label l = new Label("Pour réinitialiser votre mot de passe, saisissez l'adresse e-mail complète que vous utilisez pour vous connecter à votre compte.");
		vl.setMembers(l, formPanel);
		dialogWindow.addItem(vl);
		dialogWindow.draw();
		email.focusInItem();
	}
	
	public void resetAllFields(){
		loginTextItem.setValue("");
		resetPasswordFields();
	}
	
	public void resetPasswordFields(){
		passWordItem.setValue("");
	}
	
	protected void onUserConnected(CustomerDTO customerDTO_){}
	
	
}
